import factors
import inspect
n = 0
regression=False; N = 1 # run particular factor/ regression
for name, obj in inspect.getmembers(factors, predicate=inspect.isclass):
if obj.__module__ == "factors":
if n==N or regression==True:
# clear_output(wait=False)
%run -i backtest.py {name}
n = n+1
factor analysis begin: Factor_DailyReturns 2024-02-23 02:07:25.321714
analysis factor/portfolio: True/True
long-short/group neutral: True/False
strategy: eq_weight optimize: max_sharpe
simulation_time: 0
start 2014-01-01
end 2017-01-01
use_storage_data: True
Dropped 18.1% entries from factor data: 18.1% in forward returns computation and 0.0% in binning phase (set max_loss=0 to see potentially suppressed Exceptions).
max_loss is 50.0%, not exceeded: OK!
factors: (755597, 2)
prices: (756, 1655)
pf_returns: (1086,)
pf_positions: (1086, 1218)
pf_transactions: (8297, 8)
pf_benchmark: (1080,)
Quantiles Statistics
| min | max | mean | std | count | count % | |
|---|---|---|---|---|---|---|
| factor_quantile | ||||||
| 1 | 1.0 | 1570.0 | 387.059700 | 222.940334 | 124120 | 20.046936 |
| 2 | 341.0 | 2042.0 | 953.525436 | 244.402657 | 123682 | 19.976193 |
| 3 | 655.0 | 2421.0 | 1450.230185 | 259.104429 | 123683 | 19.976355 |
| 4 | 1071.0 | 2757.0 | 1952.623357 | 252.894963 | 123682 | 19.976193 |
| 5 | 1654.0 | 3137.0 | 2539.458316 | 254.748800 | 123980 | 20.024324 |
Returns Analysis
| 1D | 5D | 10D | |
|---|---|---|---|
| Ann. alpha | 0.026 | -0.003 | -0.002 |
| beta | 0.024 | 0.039 | 0.056 |
| Mean Period Wise Return Top Quantile (bps) | 0.104 | -0.383 | -0.175 |
| Mean Period Wise Return Bottom Quantile (bps) | -2.264 | -0.516 | -0.364 |
| Mean Period Wise Spread (bps) | 2.368 | 0.112 | 0.158 |
<Figure size 432x288 with 0 Axes>
Information Analysis
| 1D | 5D | 10D | |
|---|---|---|---|
| IC Mean | 0.003 | -0.001 | -0.001 |
| IC Std. | 0.135 | 0.137 | 0.134 |
| Risk-Adjusted IC | 0.020 | -0.005 | -0.005 |
| t-stat(IC) | 0.550 | -0.132 | -0.127 |
| p-value(IC) | 0.582 | 0.895 | 0.899 |
| IC Skew | 0.057 | 0.119 | 0.095 |
| IC Kurtosis | 0.595 | 0.689 | 0.789 |
Turnover Analysis
| 10D | 1D | 5D | |
|---|---|---|---|
| Quantile 1 Mean Turnover | 0.776 | 0.767 | 0.776 |
| Quantile 2 Mean Turnover | 0.791 | 0.791 | 0.789 |
| Quantile 3 Mean Turnover | 0.779 | 0.765 | 0.776 |
| Quantile 4 Mean Turnover | 0.794 | 0.788 | 0.791 |
| Quantile 5 Mean Turnover | 0.767 | 0.761 | 0.762 |
| 1D | 5D | 10D | |
|---|---|---|---|
| Mean Factor Rank Autocorrelation | -0.014 | 0.003 | 0.006 |
<Figure size 432x288 with 0 Axes>
Entire data start date: 2014-01-03 Entire data end date: 2016-12-22 Backtest months: 51
| Backtest | |
|---|---|
| Annual return | 0.0% |
| Cumulative returns | 0.0% |
| Annual volatility | 1.1% |
| Sharpe ratio | 0.01 |
| Calmar ratio | 0.00 |
| Stability | 0.06 |
| Max drawdown | -4.3% |
| Omega ratio | 1.00 |
| Sortino ratio | 0.02 |
| Skew | -0.05 |
| Kurtosis | 4.72 |
| Tail ratio | 0.86 |
| Daily value at risk | -0.1% |
| Gross leverage | 0.71 |
| Daily turnover | 4.2% |
| Alpha | -0.00 |
| Beta | 0.01 |
| Worst drawdown periods | Net drawdown in % | Peak date | Valley date | Recovery date | Duration |
|---|---|---|---|---|---|
| 0 | 4.31 | 2016-04-12 | 2016-11-15 | NaT | NaN |
| 1 | 2.93 | 2014-07-08 | 2015-07-29 | 2016-03-24 | 448 |
| 2 | 0.62 | 2014-01-05 | 2014-01-23 | 2014-04-04 | 65 |
| 3 | 0.25 | 2014-04-08 | 2014-04-14 | 2014-04-17 | 8 |
| 4 | 0.22 | 2014-06-10 | 2014-06-20 | 2014-06-27 | 14 |
| Stress Events | mean | min | max |
|---|---|---|---|
| Apr14 | 0.04% | -0.10% | 0.19% |
| Oct14 | -0.02% | -0.24% | 0.33% |
| Fall2015 | 0.01% | -0.26% | 0.24% |
| New Normal | 0.00% | -0.40% | 0.33% |
In-sample months: 47 Out-of-sample months: 3
| All | In-sample | Out-of-sample | |
|---|---|---|---|
| Annual return | -0.0% | -0.1% | 0.4% |
| Cumulative returns | -0.1% | -0.2% | 0.1% |
| Annual volatility | 1.1% | 1.1% | 1.2% |
| Sharpe ratio | -0.02 | -0.05 | 0.31 |
| Calmar ratio | -0.01 | -0.02 | 0.22 |
| Stability | 0.05 | 0.00 | 0.02 |
| Max drawdown | -4.3% | -3.0% | -1.7% |
| Omega ratio | 1.00 | 0.99 | 1.06 |
| Sortino ratio | -0.03 | -0.06 | 0.45 |
| Skew | -0.05 | -0.06 | 0.04 |
| Kurtosis | 4.70 | 5.10 | 1.06 |
| Tail ratio | 0.86 | 0.87 | 1.11 |
| Daily value at risk | -0.1% | -0.1% | -0.2% |
| Gross leverage | 0.71 | 0.71 | 0.73 |
| Daily turnover | 4.2% | 4.3% | 3.3% |
| Alpha | -0.00 | -0.00 | 0.01 |
| Beta | 0.01 | 0.01 | -0.01 |
from IPython.display import Javascript, clear_output
from nbconvert import HTMLExporter
def save_notebook():
display(
Javascript("IPython.notebook.save_notebook()"),
include=['application/javascript']
)
def output_HTML(current_file, output_file):
import codecs
import nbformat
exporter = HTMLExporter()
output_notebook = nbformat.read(current_file, as_version=4)
output, resources = exporter.from_notebook_node(output_notebook)
file = codecs.open(output_file, 'w', encoding='utf-8')
file.write(output)
file.close()
print('saved: ', name)
current_file = 'regression.ipynb'
output_file = f'results/factor_{name}.html'
output_HTML(current_file, output_file)
saved: WeightedAverageValue